package com.example.a_java.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.a_java.common.Result;
import com.example.a_java.model.dto.report.*;
import com.example.a_java.service.ReportService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;

/**
 * 统计报表控制器
 * 提供各类业务和贷款数据的统计报表接口
 */
@RestController
@RequestMapping("/report")
@Tag(name = "统计报表接口", description = "提供各类业务和贷款数据的统计报表接口")
public class ReportController {

    @Autowired
    private ReportService reportService;

    /**
     * 获取业务统计概览数据
     */
    @GetMapping("/business/stats")
    @Operation(summary = "获取业务统计概览数据", description = "获取指定日期范围内的业务数据统计概览")
    @PreAuthorize("hasAuthority('report:business:view')")
    public Result<BusinessStatsDTO> getBusinessStats(
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
        
        BusinessStatsDTO stats = reportService.getBusinessStats(startDate, endDate);
        return Result.success(stats);
    }

    /**
     * 获取业务图表数据
     */
    @GetMapping("/business/charts")
    @Operation(summary = "获取业务图表数据", description = "获取业务数据的趋势图和分布图数据")
    @PreAuthorize("hasAuthority('report:business:view')")
    public Result<BusinessChartDTO> getBusinessCharts(
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @Parameter(description = "统计周期") @RequestParam(required = false, defaultValue = "month") String period) {
        
        BusinessQueryDTO query = new BusinessQueryDTO();
        query.setStartDate(startDate);
        query.setEndDate(endDate);
        query.setPeriod(period);
        
        BusinessChartDTO charts = reportService.getBusinessCharts(query);
        return Result.success(charts);
    }

    /**
     * 获取业务明细列表
     */
    @GetMapping("/business/list")
    @Operation(summary = "获取业务明细列表", description = "分页获取业务明细数据")
    @PreAuthorize("hasAuthority('report:business:view')")
    public Result<Page<BusinessDetailDTO>> getBusinessList(
            @Parameter(description = "当前页码") @RequestParam(required = false, defaultValue = "1") Integer currentPage,
            @Parameter(description = "每页记录数") @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @Parameter(description = "业务类型") @RequestParam(required = false) String businessType) {
        
        BusinessQueryDTO query = new BusinessQueryDTO();
        query.setCurrentPage(currentPage);
        query.setPageSize(pageSize);
        query.setStartDate(startDate);
        query.setEndDate(endDate);
        query.setBusinessType(businessType);
        
        Page<BusinessDetailDTO> page = reportService.getBusinessList(query);
        return Result.success(page);
    }

    /**
     * 导出业务报表
     */
    @PostMapping("/business/export")
    @Operation(summary = "导出业务报表", description = "导出业务报表数据为Excel文件")
    @PreAuthorize("hasAuthority('report:business:export')")
    public ResponseEntity<byte[]> exportBusinessReport(@RequestBody BusinessQueryDTO query) {
        byte[] data = reportService.exportBusinessReport(query);
        
        String fileName = "业务报表_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx";
        String encodedFileName = new String(fileName.getBytes(), java.nio.charset.StandardCharsets.ISO_8859_1);
        
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName)
                .body(data);
    }

    /**
     * 获取贷款统计概览数据
     */
    @GetMapping("/loan/stats")
    @Operation(summary = "获取贷款统计概览数据", description = "获取指定条件的贷款数据统计概览")
    @PreAuthorize("hasAuthority('report:loan:view')")
    public Result<LoanStatsDTO> getLoanStats(
            @Parameter(description = "统计周期") @RequestParam(required = false) String period,
            @Parameter(description = "日期范围") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") List<LocalDate> dateRange,
            @Parameter(description = "产品类型") @RequestParam(required = false) String productType) {
        
        LoanQueryDTO query = new LoanQueryDTO();
        query.setPeriod(period);
        query.setDateRange(dateRange);
        query.setProductType(productType);
        
        LoanStatsDTO stats = reportService.getLoanStats(query);
        return Result.success(stats);
    }

    /**
     * 获取贷款图表数据
     */
    @GetMapping("/loan/charts")
    @Operation(summary = "获取贷款图表数据", description = "获取贷款数据的趋势图和分布图数据")
    @PreAuthorize("hasAuthority('report:loan:view')")
    public Result<LoanChartDTO> getLoanCharts(
            @Parameter(description = "统计周期") @RequestParam(required = false) String period,
            @Parameter(description = "日期范围") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") List<LocalDate> dateRange,
            @Parameter(description = "产品类型") @RequestParam(required = false) String productType) {
        
        LoanQueryDTO query = new LoanQueryDTO();
        query.setPeriod(period);
        query.setDateRange(dateRange);
        query.setProductType(productType);
        
        LoanChartDTO charts = reportService.getLoanCharts(query);
        return Result.success(charts);
    }

    /**
     * 获取贷款明细列表
     */
    @GetMapping("/loan/list")
    @Operation(summary = "获取贷款明细列表", description = "分页获取贷款明细数据")
    @PreAuthorize("hasAuthority('report:loan:view')")
    public Result<Page<Map<String, Object>>> getLoanList(
            @Parameter(description = "当前页码") @RequestParam(required = false, defaultValue = "1") Integer currentPage,
            @Parameter(description = "每页记录数") @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @Parameter(description = "统计周期") @RequestParam(required = false) String period,
            @Parameter(description = "日期范围") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") List<LocalDate> dateRange,
            @Parameter(description = "产品类型") @RequestParam(required = false) String productType,
            @Parameter(description = "贷款状态") @RequestParam(required = false) String loanStatus,
            @Parameter(description = "排序字段") @RequestParam(required = false) String orderBy,
            @Parameter(description = "排序方式") @RequestParam(required = false, defaultValue = "desc") String orderType) {
        
        LoanQueryDTO query = new LoanQueryDTO();
        query.setCurrentPage(currentPage);
        query.setPageSize(pageSize);
        query.setPeriod(period);
        query.setDateRange(dateRange);
        query.setProductType(productType);
        query.setLoanStatus(loanStatus);
        query.setOrderBy(orderBy);
        query.setOrderType(orderType);
        
        Page<Map<String, Object>> page = reportService.getLoanList(query);
        return Result.success(page);
    }

    /**
     * 导出贷款报表
     */
    @PostMapping("/loan/export")
    @Operation(summary = "导出贷款报表", description = "导出贷款报表数据为Excel文件")
    @PreAuthorize("hasAuthority('report:loan:export')")
    public ResponseEntity<byte[]> exportLoanReport(@RequestBody LoanQueryDTO query) {
        byte[] data = reportService.exportLoanReport(query);
        
        String fileName = "贷款报表_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx";
        String encodedFileName = new String(fileName.getBytes(), java.nio.charset.StandardCharsets.ISO_8859_1);
        
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName)
                .body(data);
    }

    /**
     * 获取风险统计概览数据
     */
    @GetMapping("/risk/stats")
    @Operation(summary = "获取风险统计概览数据", description = "获取指定日期范围内的风险数据统计概览")
    @PreAuthorize("hasAuthority('report:risk:view')")
    public Result<RiskStatsDTO> getRiskStats(
            @Parameter(description = "日期范围") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") List<LocalDate> dateRange,
            @Parameter(description = "风险等级") @RequestParam(required = false) String riskLevel) {
        
        RiskStatsDTO stats = reportService.getRiskStats(dateRange, riskLevel);
        return Result.success(stats);
    }

    /**
     * 获取风险图表数据
     */
    @GetMapping("/risk/charts")
    @Operation(summary = "获取风险图表数据", description = "获取风险数据的趋势图和分布图数据")
    @PreAuthorize("hasAuthority('report:risk:view')")
    public Result<Map<String, Object>> getRiskCharts(
            @Parameter(description = "日期范围") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") List<LocalDate> dateRange,
            @Parameter(description = "风险等级") @RequestParam(required = false) String riskLevel) {
        
        Map<String, Object> charts = reportService.getRiskCharts(dateRange, riskLevel);
        return Result.success(charts);
    }

    /**
     * 获取风险明细列表
     */
    @GetMapping("/risk/list")
    @Operation(summary = "获取风险明细列表", description = "分页获取风险明细数据")
    @PreAuthorize("hasAuthority('report:risk:view')")
    public Result<Page<Map<String, Object>>> getRiskList(
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @Parameter(description = "风险等级") @RequestParam(required = false) String riskLevel,
            @Parameter(description = "客户名称") @RequestParam(required = false) String customerName,
            @Parameter(description = "当前页码") @RequestParam(required = false, defaultValue = "1") Integer currentPage,
            @Parameter(description = "每页大小") @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        
        Page<Map<String, Object>> page = reportService.getRiskList(startDate, endDate, riskLevel, customerName, currentPage, pageSize);
        return Result.success(page);
    }

    /**
     * 导出风险报表
     */
    @GetMapping("/risk/export")
    @Operation(summary = "导出风险报表", description = "导出风险报表数据为Excel文件")
    @PreAuthorize("hasAuthority('report:risk:export')")
    public ResponseEntity<byte[]> exportRiskReport(
            @Parameter(description = "开始日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @Parameter(description = "风险等级") @RequestParam(required = false) String riskLevel,
            @Parameter(description = "导出类型(summary/detail)") @RequestParam(defaultValue = "summary") String exportType) {
        
        byte[] data = reportService.exportRiskReport(startDate, endDate, riskLevel, exportType);
        
        String fileName = "风险报表_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx";
        String encodedFileName = new String(fileName.getBytes(), java.nio.charset.StandardCharsets.ISO_8859_1);
        
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName)
                .body(data);
    }

    /**
     * 获取逾期统计数据
     */
    @GetMapping("/overdue/stats")
    @Operation(summary = "获取逾期统计数据", description = "获取指定日期范围内的逾期数据统计")
    @PreAuthorize("hasAuthority('report:overdue:view')")
    public Result<OverdueStatsDTO> getOverdueStats(
            @Parameter(description = "日期范围") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") List<LocalDate> dateRange) {
        
        OverdueStatsDTO stats = reportService.getOverdueStats(dateRange);
        return Result.success(stats);
    }

    /**
     * 获取放款统计概览数据
     */
    @GetMapping("/lending/stats")
    @Operation(summary = "获取放款统计概览数据", description = "获取指定日期范围内的放款数据统计概览")
    @PreAuthorize("hasAuthority('report:lending:view')")
    public Result<LendingStatsDTO> getLendingStats(
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
        
        LendingStatsDTO stats = reportService.getLendingStats(startDate, endDate);
        return Result.success(stats);
    }

    /**
     * 获取放款图表数据
     */
    @GetMapping("/lending/charts")
    @Operation(summary = "获取放款图表数据", description = "获取放款数据的趋势图和分布图数据")
    @PreAuthorize("hasAuthority('report:lending:view')")
    public Result<Map<String, Object>> getLendingCharts(
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @Parameter(description = "统计周期(day/week/month/quarter/year)") @RequestParam(required = false, defaultValue = "month") String period) {
        
        Map<String, Object> charts = reportService.getLendingCharts(startDate, endDate, period);
        return Result.success(charts);
    }

    /**
     * 获取放款明细列表
     */
    @GetMapping("/lending/list")
    @Operation(summary = "获取放款明细列表", description = "分页获取放款明细数据")
    @PreAuthorize("hasAuthority('report:lending:view')")
    public Result<Page<Map<String, Object>>> getLendingList(
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @Parameter(description = "产品类型") @RequestParam(required = false) String productType,
            @Parameter(description = "客户名称") @RequestParam(required = false) String customerName,
            @Parameter(description = "当前页码") @RequestParam(required = false, defaultValue = "1") Integer currentPage,
            @Parameter(description = "每页大小") @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        
        Page<Map<String, Object>> page = reportService.getLendingList(startDate, endDate, productType, customerName, currentPage, pageSize);
        return Result.success(page);
    }

    /**
     * 获取放款失败分析
     */
    @GetMapping("/lending/failure-analysis")
    @Operation(summary = "获取放款失败分析", description = "获取指定日期范围内的放款失败分析数据")
    @PreAuthorize("hasAuthority('report:lending:view')")
    public Result<Map<String, Object>> getLendingFailureAnalysis(
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
        
        Map<String, Object> analysis = reportService.getLendingFailureAnalysis(startDate, endDate);
        return Result.success(analysis);
    }

    /**
     * 导出放款报表
     */
    @GetMapping("/lending/export")
    @Operation(summary = "导出放款报表", description = "导出放款报表数据为Excel文件")
    @PreAuthorize("hasAuthority('report:lending:export')")
    public ResponseEntity<byte[]> exportLendingReport(
            @Parameter(description = "开始日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @Parameter(description = "产品类型") @RequestParam(required = false) String productType,
            @Parameter(description = "导出类型(summary/detail)") @RequestParam(defaultValue = "summary") String exportType) {
        
        byte[] data = reportService.exportLendingReport(startDate, endDate, productType, exportType);
        
        String fileName = "放款报表_" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx";
        String encodedFileName = new String(fileName.getBytes(), java.nio.charset.StandardCharsets.ISO_8859_1);
        
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName)
                .body(data);
    }

    /**
     * 获取放款效率分析
     */
    @GetMapping("/lending/efficiency")
    @Operation(summary = "获取放款效率分析", description = "获取指定日期范围内的放款效率分析数据")
    @PreAuthorize("hasAuthority('report:lending:view')")
    public Result<Map<String, Object>> getLendingEfficiency(
            @Parameter(description = "开始日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
        
        Map<String, Object> efficiency = reportService.getLendingEfficiency(startDate, endDate);
        return Result.success(efficiency);
    }
} 
